from flask import Flask
from flask_login import LoginManager,current_user
from .app_config import app_config
from .database import *

login_manager = LoginManager()

def create_app(config_name='default'):
    app = Flask(__name__,template_folder="templates")
    app.config.from_object(app_config[config_name])
    
    # 初始化数据库
    db.init_app(app)
    init_db(app)

    login_manager.init_app(app)
    login_manager.login_view = 'auth.login'
    
    # 注册蓝图
    from .routes import main_bp
    from .auth import auth_bp
    from .file_manager import file_bp
    from .network_tools import network_bp
    
    app.register_blueprint(main_bp)
    app.register_blueprint(auth_bp, url_prefix='/auth')
    app.register_blueprint(file_bp, url_prefix='/files')
    app.register_blueprint(network_bp, url_prefix='/network')
    
    # 确保上传目录存在
    import os
    if not os.path.exists(app.config['UPLOAD_FOLDER']):
        os.makedirs(app.config['UPLOAD_FOLDER'])
    
    # 创建数据库表
    with app.app_context():
        db.create_all()
        
        # 创建默认管理员用户（如果不存在）
        from .models import User
        admin = User.query.filter_by(username='admin').first()
        if not admin:
            admin = User(username='admin')
            admin.set_password('admin123')
            db.session.add(admin)
            db.session.commit()
    # 用户加载回调 - 必须定义在应用工厂函数内
    @login_manager.user_loader
    def load_user(user_id):
        """加载用户的回调函数，必须返回 User 对象或 None"""
        try:
            # 使用当前应用的上下文
            with app.app_context():
                # 将 user_id 转换为整数
                user = User.query.get(int(user_id))
                if user:
                    app.logger.debug(f"Loaded user: {user.username} (ID: {user_id})")
                else:
                    app.logger.warning(f"User not found for ID: {user_id}")
                return user
        except Exception as e:
            app.logger.error(f"Error loading user {user_id}: {str(e)}")
            return None
        
    # 将current_user注入所有模板
    @app.context_processor
    def inject_user():
        return dict(current_user=current_user)
    
    return app